/*package com.mstar.qs.basic.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.morningstar.qs.basic.db.dao.AddOnServiceInfoService;
import com.morningstar.qs.basic.db.dao.ExchangesService;
import com.morningstar.qs.basic.db.dao.LanguageService;
import com.morningstar.qs.basic.db.dao.MarketsService;
import com.morningstar.qs.basic.db.dao.PermissionService;
import com.morningstar.qs.basic.db.dao.SecuritiesService;
import com.morningstar.qs.basic.db.dto.AddOnServiceInfoDto;
import com.morningstar.qs.basic.db.dto.ComponentDto;
import com.morningstar.qs.basic.db.dto.ExchangesDto;
import com.morningstar.qs.basic.db.dto.FunctionInfoDto;
import com.morningstar.qs.basic.db.dto.GroupInfoDto;
import com.morningstar.qs.basic.db.dto.InstProfileDto;
import com.morningstar.qs.basic.db.dto.InstitutionDto;
import com.morningstar.qs.basic.db.dto.LableItemDto;
import com.morningstar.qs.basic.db.dto.MarketsDto;
import com.morningstar.qs.basic.db.dto.SecuritiesDto;
import com.morningstar.qs.basic.db.dto.TargetLangDto;
import com.morningstar.qs.basic.db.util.BeanBase;
import com.mstar.qs.common.bean.CommonExchange;
import com.mstar.qs.common.bean.CommonMarket;
import com.mstar.qs.common.bean.CommonSecurity;

public class InitService {
	private static boolean INIT_STATUS = false;
	private static final String DEFAULT_LANGUAGE = "en";
	private static Logger log = Logger.getLogger(InitService.class);
	private static Object lock = new Object();

	private InitInfo initInfo = new InitInfo();

	private static InitService instance = new InitService();
	private LanguageService ls = new LanguageService();
	private PermissionService ps = new PermissionService();

	private InitService() {
		if (!INIT_STATUS)
			initAll();

	}

	public static InitService getInstance() {
		return instance;
	}

	public void initAll() {
		synchronized (lock) {
			if (INIT_STATUS)
				return;
			try {
				initMultiLanguage();
				initPermission();
				initExchanges();
				initProfile();
				INIT_STATUS = true;
			} catch (Exception e) {
				e.printStackTrace();
				log.error("\t\t *** Failed to load init information ...");
			}
		}
	}

	public void initProfile() {
		initInfo.initProfile();
	}

	public void initMultiLanguage() {
		Map<Integer, LableItemDto> lis = ls.obtainAllLables();
		Map<Integer, Set<Integer>> comps = ls.obtainLangRelationship();
		initInfo.initLanguage(comps, lis);
	}

	public void initPermission() {
		try {
			List<FunctionInfoDto> fids = ps.obtainAllFunctions();
			List<ComponentDto> cds = ps.obtainAllComponents();
			List<GroupInfoDto> gids = ps.findGroups();
			List<InstitutionDto> insts = ps.findAllInstList();

			initInfo.initPermission(cds, fids, gids, insts);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void initExchanges() {
		try {
			List<ExchangesDto> list = new ExchangesService().findAll();
			List<SecuritiesDto> sds = new SecuritiesService().findAll();
			List<MarketsDto> mds = new MarketsService().findAll();
			initInfo.initExchanges(BeanBase.convert(list, CommonExchange.class), BeanBase.convert(sds, CommonSecurity.class), BeanBase.convert(mds, CommonMarket.class));
		} catch (Throwable e) {
			e.printStackTrace();
		}
	}

	public InitInfo getInitInfo() {
		return initInfo;
	}

	public final class InitInfo implements Serializable {

		*//**
		 * 
		 *//*
		private static final long serialVersionUID = 4619663128228471492L;

		public static final String CONTEXT_PATH = "initInfo";

		private final Language language = new Language();
		private final Permission permission = new Permission();
		private final Profile profile = new Profile();
		private final MarketInfo marketInfo = new MarketInfo();

		private InitInfo() {
		};

		*//**
		 * Initialize multi-language information
		 * 
		 * @param componentId2Lables
		 *            Lables' id that component id specified by key is related
		 *            to
		 * @param lableId2Languages
		 *            Muli-languages that Lable connected by key is
		 *            corresponding to
		 *//*
		private void initLanguage(
				Map<Integer, Set<Integer>> componentId2Lables,
				Map<Integer, LableItemDto> lableId2Languages) {
			language.reset();
			language.init(componentId2Lables, lableId2Languages);
		}

		private void initPermission(List<ComponentDto> cds,
				List<FunctionInfoDto> fids, List<GroupInfoDto> gids,
				List<InstitutionDto> insts) {
			Map<String, ComponentDto> comps = new HashMap<String, ComponentDto>();
			Map<String, FunctionInfoDto> funcs = new HashMap<String, FunctionInfoDto>();
			Map<String, GroupInfoDto> groups = new HashMap<String, GroupInfoDto>();
			Map<String, InstitutionDto> mapInsts = new HashMap<String, InstitutionDto>();

			for (ComponentDto c : cds) {
				comps.put(c.getCompCode(), c);
			}
			for (FunctionInfoDto f : fids) {
				funcs.put(f.getFunctionId(), f);
			}

			for (GroupInfoDto g : gids) {
				groups.put(g.getGroupName(), g);
			}
			for (InstitutionDto dto : insts) {
				mapInsts.put(dto.getInstCode(), dto);
			}

			permission.setComps(comps);
			permission.setFuncs(funcs);
			permission.setGroups(groups);
			permission.setInsts(mapInsts);
		}

		private void initProfile() {
			profile.initProfile();
		}

		private void initExchanges(List<CommonExchange> eds,
				List<CommonSecurity> sds, List<CommonMarket> mds) {
			marketInfo.initExchanges(eds, sds, mds);

		}
		
		public MarketInfo marketInfo() {
			return marketInfo;
		}
		
		public Permission permission() {
			return permission;
		}
		
		public Language language() {
			return language;
		}
		
		public Profile profile() {
			return profile;
		}

		public class Language {

			*//**
			 * Keys are the component's ids. Values are Lable item's ids
			 *//*
			private final Map<Integer, Set<Integer>> componentId2Lables = new HashMap<Integer, Set<Integer>>();

			*//**
			 * Keys are Lable item's ids. values are lable item objects.
			 *//*
			private final Map<Integer, LableItemDto> lableId2Languages = new HashMap<Integer, LableItemDto>();

			*//**
			 * Keys are Lable items. Values are Lable item's ids.
			 *//*
			private final Map<String, Integer> Lable2LableId = new HashMap<String, Integer>();

			public void init(Map<Integer, Set<Integer>> componentId2Lables,
					Map<Integer, LableItemDto> lableId2Languages) {
				// log.info(lableId2Languages);
				if (componentId2Lables != null && componentId2Lables.size() > 0)
					this.componentId2Lables.putAll(componentId2Lables);
				if (lableId2Languages != null && lableId2Languages.size() > 0)
					this.lableId2Languages.putAll(lableId2Languages);
				initLable2LableId();
			}

			public void reset() {
				componentId2Lables.clear();
				lableId2Languages.clear();
				Lable2LableId.clear();
			}

			private void initLable2LableId() {
				for (Map.Entry<Integer, LableItemDto> en : lableId2Languages
						.entrySet()) {
					LableItemDto dto = en.getValue();
					Lable2LableId.put(dto.getLable(), dto.getLablItemId());
				}

			}

			public String toString() {
				StringBuilder sb = new StringBuilder();
				if (componentId2Lables != null) {
					for (Map.Entry<Integer, Set<Integer>> en : componentId2Lables
							.entrySet()) {
						sb.append("Component:").append(en.getKey())
								.append("\r\n");
						for (Integer li : en.getValue()) {
							sb.append("\t")
									.append(lableId2Languages.get(li)
											.toString()).append("\r\n");
						}
					}
				}
				return sb.toString();
			}

			protected List<LableItemDto> getLableByCompId(Integer compId) {
				Set<Integer> lables = componentId2Lables.get(compId);
				if (lables == null)
					return null;
				List<LableItemDto> dtos = new ArrayList<LableItemDto>();
				for (Integer lab : lables) {
					dtos.add(lableId2Languages.get(lab));
				}
				return dtos;
			}

			protected Integer retreiveLableId(String lable) {
				assert lable != null;
				assert Lable2LableId != null;
				Integer lableId = Lable2LableId.get(lable);
				return lableId;
			}

			protected boolean checkLanguage(String lable, String languageType) {
				if (lable == null || languageType == null)
					throw new IllegalArgumentException();
				Integer li = Lable2LableId.get(lable);
				if (li == null)
					return false;

				LableItemDto lid = lableId2Languages.get(li);
				if (lid == null)
					return false;
				TargetLangDto tld = lid.getLang(languageType);
				if (tld == null)
					return false;
				return true;
			}

			protected TargetLangDto retrieveTargLang(Integer lid,
					String langType) {
				LableItemDto langs = lableId2Languages.get(lid);
				return langs.findByLangType(langType);
			}

			protected LableItemDto retrieveLable(Integer lableId) {
				return lableId2Languages.get(lableId);
			}

			protected Collection<LableItemDto> retrieveAllLables() {
				return lableId2Languages.values();
			}

			protected boolean checkRelationship(Integer lableId, int compId) {
				Set<Integer> lbis = componentId2Lables.get(compId);
				if (lbis == null)
					return false;
				System.out.println("CompId:" + compId + " libs:"
						+ lbis.toString());
				return lbis.contains(lableId);
			}

			*//**
			 * retrieve target language in terms of specified language type with
			 * component code.
			 * 
			 * @param compCode
			 * @param langType
			 * @return
			 *//*
			protected List<LanguageEntity> retrieveTarggetLanguage(
					String compCode, String langType) {
				if (compCode == null || compCode.length() == 0
						|| langType == null || langType.length() == 0)
					throw new NullPointerException();
				ComponentDto comp = permission.findComp(compCode);
				if (comp == null) {
					log.warn("Cannot find component with compCode: " + compCode);
					throw new NullPointerException();
				}
				Set<Integer> lis = componentId2Lables.get(comp.getCompId());
				if (lis == null) {
					log.warn("Cannot find lables with component id:"
							+ comp.getCompId() + "/" + compCode);
					return null;
				} else {
					List<LanguageEntity> les = new ArrayList<LanguageEntity>();
					if (langType.equals(DEFAULT_LANGUAGE)) {
						for (Integer li : lis) {
							LableItemDto lid = lableId2Languages.get(li);
							LanguageEntity le = new LanguageEntity();
							le.setLable(lid.getLable()).setTargetLanguage(
									lid.getStandardLang());

							les.add(le);
						}
					} else {
						for (Integer li : lis) {
							LableItemDto lid = lableId2Languages.get(li);
							if (lid != null) {
								TargetLangDto tld = lid.getLang(langType);
								if (tld != null) {
									LanguageEntity le = new LanguageEntity();
									le.setLable(lid.getLable())
											.setTargetLanguage(
													tld.getTargLangValue());
									les.add(le);
								}
							}
						}
					}
					if (les.size() > 0)
						return les;
				}
				return null;
			}
		}

		public class MarketInfo {

			// ** ExchangeID : CommonExchange
			private final Map<Integer, CommonExchange> exchanges = new HashMap<Integer, CommonExchange>();
			*//**
			 * miccode --> exchange id
			 *//*
			private final Map<String, Integer> miccode2ExchangeId = new HashMap<String, Integer>();

			*//**
			 * security type --> securities
			 *//*
			private final Map<Integer, CommonSecurity> securities = new HashMap<Integer, CommonSecurity>();

			*//**
			 * exchange id --> {security type --> markets}
			 *//*
			private final Map<Integer, Map<Integer, CommonMarket>> markets = new HashMap<Integer, Map<Integer, CommonMarket>>();
			private final List<CommonMarket> marketsList = new ArrayList<CommonMarket>();

			private void initExchanges(List<CommonExchange> eds,
					List<CommonSecurity> sds, List<CommonMarket> mds) {
				if (eds != null && eds.size() > 0) {
					initAndMapExchanges(eds);
				}
				if (sds != null && sds.size() > 0) {
					initSecu(sds);
				}
				if (mds != null && mds.size() > 0) {
					initMark(mds);
				}

			}

			public CommonMarket retrieveMarkets(int exchId, int secType) {
				Map<Integer, CommonMarket> exc = markets.get(exchId);
				if (exc != null) {
					return exc.get(secType);
				}
				return null;
			}

			public CommonExchange retrieveExchanges(String miccode) {
				assert miccode != null && miccode.length() > 0;
				Integer exchId = miccode2ExchangeId.get(miccode);
				return exchanges.get(exchId);
			}
			public CommonExchange retrieveExchanges(int exch) {
				if(exch<=0) throw new IllegalArgumentException();
				return exchanges.get(exch);
			}
			
			public Map<Integer, CommonSecurity> retrieveSecurities() {
				return securities;
			}


			private void initMark(List<CommonMarket> mds) {
				assert mds != null && mds.size() > 0;
				marketsList.addAll(mds);
				for (CommonMarket md : mds) {
					int exchId = md.getExchId();
					int secType = md.getSecuType();
					Map<Integer, CommonMarket> exc = markets.get(exchId);
					if (exc == null) {
						exc = new HashMap<Integer, CommonMarket>();
						markets.put(exchId, exc);
					}
					exc.put(secType, md);
				}
			}

			private void initSecu(List<CommonSecurity> sds) {
				assert sds != null && sds.size() > 0;
				for (CommonSecurity sd : sds) {
					securities.put(sd.getSecuType(), sd);
				}
			}

			private void initAndMapExchanges(List<CommonExchange> eds) {
				assert eds != null && eds.size() > 0;
				for (CommonExchange ed : eds) {
					exchanges.put(ed.getExchId(), ed);
					mapMiccode2ExchangeId(ed);
				}
			}

			private void mapMiccode2ExchangeId(CommonExchange ed) {
				assert ed != null;
				String mic = ed.getMicCode();
				if (mic != null && mic.length() > 0) {
					String mics[] = mic.split(",");
					for (int i = 0; i < mics.length; i++) {
						assert mics[i] != null && mics[i].length() > 0;
						if (mics[i] != null && mics[i].length() > 0) {
							miccode2ExchangeId.put(mics[i], ed.getExchId());
						}
					}
				}
			}

			protected List<CommonMarket> getMarkets() {
				return new ArrayList<CommonMarket>(marketsList);
			}

			protected Collection<CommonExchange> getExchanges() {
				return exchanges.values();
			}

		}

		public class Permission {
			*//**
			 * All components information with component code as key
			 *//*
			Map<String, ComponentDto> comps;

			*//**
			 * Map component id to component code
			 *//*
			Map<Integer, String> compID2Code;

			*//**
			 * All function information with function code as key
			 *//*
			Map<String, FunctionInfoDto> funcs;

			*//**
			 * All group information with group name as key
			 *//*
			Map<String, GroupInfoDto> groups;

			*//**
			 * All institution information with institution code
			 *//*
			Map<String, InstitutionDto> insts;

			List<AddOnServiceInfoDto> addOnServices = null;

			public List<AddOnServiceInfoDto> getAddOnServices() {
				if (addOnServices == null) {
					AddOnServiceInfoService addOnService = new AddOnServiceInfoService();
					addOnServices = addOnService.findAll();
				}
				return addOnServices;
			}

			public void setAddOnServices(List<AddOnServiceInfoDto> addOnServices) {
				this.addOnServices = addOnServices;
			}

			public String retrieveCompCode(int compId) {
				for (Map.Entry<String, ComponentDto> en : comps.entrySet()) {
					if (en.getValue().getCompId() == compId)
						return en.getValue().getCompCode();
				}
				return null;
			}

			public Map<String, InstitutionDto> getInsts() {
				return insts;
			}

			public void setInsts(Map<String, InstitutionDto> insts) {
				this.insts = insts;
			}

			public Map<String, ComponentDto> getComps() {
				return comps;
			}

			public FunctionInfoDto retrieveFunction(String funcId) {
				return funcs.get(funcId);
			}

			public void setComps(Map<String, ComponentDto> comps) {
				this.comps = comps;
			}

			public Map<String, FunctionInfoDto> getFuncs() {
				return funcs;
			}

			public void setFuncs(Map<String, FunctionInfoDto> funcs) {
				this.funcs = funcs;
			}

			public Map<String, GroupInfoDto> getGroups() {
				return groups;
			}

			public void setGroups(Map<String, GroupInfoDto> groups) {
				this.groups = groups;
			}

			public ComponentDto findComp(String compCode) {
				return comps.get(compCode);
			}

			public ComponentDto findComp(Integer compId) {
				for (Map.Entry<String, ComponentDto> en : comps.entrySet()) {
					if (en.getValue().getCompId() == compId)
						return en.getValue();
				}
				return null;
			}

		}

		*//**
		 * Profile that caches all profile information corresponding to current
		 * user.
		 * 
		 * @author dchen2
		 * 
		 *//*
		public class Profile {
			*//**
			 * Institution's profiles related to current user. Institution code
			 * is as key
			 *//*
			Map<String, InstProfileDto> insProfile;

			public void initProfile() {
				// TODO Auto-generated method stub

			}
		}

		*//**
		 * Check whether or not including the translated language type
		 * corresponding to specified lable item and
		 * 
		 * @param lable
		 * @param language2
		 * @return
		 *//*
		public boolean checkTargetLanguage(String lable, String languageType) {
			return language.checkLanguage(lable, languageType);
		}

		public Integer retrieveLableId(String lable) {
			return language.retreiveLableId(lable);
		}

		public List<? extends CommonMarket> getMarkets() {
			return marketInfo.getMarkets();
		}

		public Collection<? extends CommonExchange> getExchanges() {
			return marketInfo.getExchanges();
		}

		public LableItemDto retrieveLableByLablId(Integer lableId) {
			return language.retrieveLable(lableId);
		}

		public TargetLangDto retrieveTargLang(Integer lid, String langType) {
			return language.retrieveTargLang(lid, langType);
		}

		public ComponentDto retrieveComponetByCompCode(String compCode) {
			return permission.findComp(compCode);
		}

		public ComponentDto retrieveComponetByByCompId(Integer compId) {
			return permission.findComp(compId);
		}

		public Collection<LableItemDto> retrieveAllLables() {
			return language.retrieveAllLables();
		}

		public boolean checkRelationship(Integer lableId, int compId) {
			return language.checkRelationship(lableId, compId);
		}

		public List<LableItemDto> retrieveLablesByCompId(Integer compId) {
			return language.getLableByCompId(compId);
		}

		public FunctionInfoDto retrieveFunctionByFuncId(String funcId) {
			return permission.retrieveFunction(funcId);
		}

		public List<LanguageEntity> retrieveTarggetLanguage(String compCode,
				String langType) {
			return language.retrieveTarggetLanguage(compCode, langType);
		}

		public Map<String, List<LanguageEntity>> retrieveTarggetLanguage(
				String[] compCodes, String langType) {
			Map<String, List<LanguageEntity>> rs = new HashMap<String, List<LanguageEntity>>();
			for (int i = 0; i < compCodes.length; i++) {
				rs.put(compCodes[i],
						retrieveTarggetLanguage(compCodes[i], langType));
			}
			return rs;
		}

		public Map<String, GroupInfoDto> retrieveGroupInfo() {
			return permission.getGroups();
		}

		public Map<String, InstitutionDto> retrieveInstitution() {
			return permission.getInsts();
		}

		public List<AddOnServiceInfoDto> retrieveAddOnServices() {
			return this.permission.getAddOnServices();
		}
		
		public List<String> retrieveAddOnSourceCode() {
			List<AddOnServiceInfoDto> as=retrieveAddOnServices();
			if(as==null || as.size()==0) return null;
			List<String> a=new ArrayList<String>();
			for(AddOnServiceInfoDto dto: as) {
				a.add(dto.getAddOnCode());
			}
			return a;
		}
		

		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append(language.toString());
			return sb.toString();
		}

	}

	public static class LanguageEntity {
		private String lable;
		private String targetLanguage;

		public String getLable() {
			return lable;
		}

		public LanguageEntity setLable(String lable) {
			this.lable = lable;
			return this;
		}

		public String getTargetLanguage() {
			return targetLanguage;
		}

		public LanguageEntity setTargetLanguage(String targetLanguage) {
			this.targetLanguage = targetLanguage;
			return this;
		}

		@Override
		public String toString() {
			return lable + ": " + targetLanguage;
		}
	}
}
*/